home *** CD-ROM | disk | FTP | other *** search
- # jedit_modes.tcl - mode-handling procedures for jedit, a tk-based editor
- #
- # Copyright 1992-1994 by Jay Sekora. All rights reserved, except
- # that this file may be freely redistributed in whole or in part
- # for non-profit, noncommercial use.
-
- # TO DO
- # ELIMINATE REDUNDANCY! both in the code and in what's done when a mode
- # is entered (I think prefs are being read more than once on startup).
- # abbrev fixes:
- # maybe some heuristics for things like plurals
- # maybe a syntax for suffixes (e.g., commit;t -> commitment)
- # file_modes panel
- # documentation for keybindings (automatic documentation?)
- # problem with filename getting set when you cancel Save
- # for the first time on a new unnamed file
- # improve find panel
- # have find wrap around (if last time didn't match)
- # regex search/replace
- # find all at once (mark) and cycle through with tag nextrange
- # gesture commands
- # autobreaking space a problem if you use two spaces betw sentences
- # word-end punctuation (and heuristics) sd be mode-specific
- #
- # PROBLEM WITH CHANGING BINDINGS ON THE FLY! (urgent)
-
- # CHANGES:
- # lots of binding changes (jbind*.tcl consistency)
- # app-specific Emacs and vi bindings
- # house(s) the s won't expand
- # return key checkpoints!
- # improved mode handling (hooks)
-
- ######################################################################
-
- ######################################################################
- # jedit:guess_mode f - guess mode based on filename f
- ######################################################################
-
- proc jedit:guess_mode { f } {
- j:debug "jedit:guess_mode $f"
- global FILE_MODES LINE_MODES
-
- #
- # first, try matching on name
- #
- foreach i $FILE_MODES {
- if [string match [lindex $i 0] $f] {
- return [lindex $i 1]
- }
- }
- #
- # then, check first line (might be a script)
- #
- if {[file exists $f]} {
- set file [open $f {r}]
- set line1 [read $file 80] ;# unix sees 32 chars, but be generous
- close $file
- foreach i $LINE_MODES {
- if [string match [lindex $i 0] $line1] {
- return [lindex $i 1]
- }
- }
- }
- #
- # no matches - just use `plain'
- #
- return plain
- }
-
- ######################################################################
- # jedit:read_mode_prefs m - read prefs in $JEDIT_MODEPREFS for mode m
- # Note that the defaults _can't_ be in $jstools_library/jeditmodes .
- ######################################################################
-
- proc jedit:read_mode_prefs { {m plain} } {
- j:debug "Reading mode prefs for mode $m."
- global JEDIT_MODEPREFS HOME
- j:read_prefs -array JEDIT_MODEPREFS -prefix $m \
- -directory $HOME/.tk/jeditmodes -file ${m}-defaults {
- {textfont default}
- {textwidth 80}
- {textheight 24}
- {textwrap char}
- {sabbrev 0}
- {dabbrev 0}
- {autobreak 0}
- {autoindent 0}
- {parenflash 0}
- {savestate 0}
- {buttonbar 1}
- {menu,editor 1}
- {menu,file 1}
- {menu,edit 1}
- {menu,prefs 0}
- {menu,abbrev 1}
- {menu,filter 1}
- {menu,format 0}
- {menu,mode1 0}
- {menu,mode2 0}
- {menu,user 1}
- }
- }
-
- ######################################################################
- # jedit:set_default_mode_prefs mode -
- # set defaults for all mode-specific preferences, so that failure
- # of a mode to specify a particular preference doesn't trigger
- # "no such variable" errors. doesn't actually read a file.
- ######################################################################
-
- proc jedit:set_default_mode_prefs { mode } {
- global JEDIT_MODEPREFS
-
- set JEDIT_MODEPREFS($mode,textfont) default
- set JEDIT_MODEPREFS($mode,textwidth) 80
- set JEDIT_MODEPREFS($mode,textheight) 24
- set JEDIT_MODEPREFS($mode,textwrap) char
- set JEDIT_MODEPREFS($mode,sabbrev) 0
- set JEDIT_MODEPREFS($mode,dabbrev) 0
- set JEDIT_MODEPREFS($mode,autobreak) 0
- set JEDIT_MODEPREFS($mode,autoindent) 0
- set JEDIT_MODEPREFS($mode,autoindent) 0
- set JEDIT_MODEPREFS($mode,parenflash) 0
- set JEDIT_MODEPREFS($mode,buttonbar) 1
- set JEDIT_MODEPREFS($mode,menu,editor) 1
- set JEDIT_MODEPREFS($mode,menu,file) 1
- set JEDIT_MODEPREFS($mode,menu,edit) 1
- set JEDIT_MODEPREFS($mode,menu,prefs) 0
- set JEDIT_MODEPREFS($mode,menu,abbrev) 1
- set JEDIT_MODEPREFS($mode,menu,filter) 1
- set JEDIT_MODEPREFS($mode,menu,format) 0
- set JEDIT_MODEPREFS($mode,menu,mode1) 0
- set JEDIT_MODEPREFS($mode,menu,mode2) 0
- set JEDIT_MODEPREFS($mode,menu,user) 1
- }
-
- ######################################################################
- # mode:plain:init - setup for plain mode
- # the presence of this proc guarantees that jedit won't ever need
- # to look for a "plain-mode.tcl" file. (the same technique could
- # be used by applications that embed jedit and need to modify its
- # behaviour.)
- ######################################################################
-
- proc mode:plain:init { t } {
- global JEDIT_MODEPREFS
-
- j:read_prefs -array JEDIT_MODEPREFS -prefix plain \
- -directory ~/.tk/jeditmodes -file plain-defaults {
- {textfont default}
- {textwidth 80}
- {textheight 24}
- {textwrap char}
- {sabbrev 0}
- {dabbrev 0}
- {autobreak 0}
- {autoindent 0}
- {parenflash 0}
- {savestate 0}
- {buttonbar 1}
- {menu,editor 1}
- {menu,file 1}
- {menu,edit 1}
- {menu,prefs 0}
- {menu,abbrev 1}
- {menu,filter 1}
- {menu,format 0}
- {menu,mode1 0}
- {menu,mode2 0}
- {menu,user 1}
- }
- }
-
- ######################################################################
- # jedit:apply_mode - apply current mode for window (menus, etc.)
- # the window can be specified either as a text widget, or as that
- # text widget's corresponding toplevel window.
- ######################################################################
-
- proc jedit:apply_mode { w } {
- j:debug "jedit:apply_mode $w"
- global HOME JEDIT_MODEPREFS tk_library jstools_library
-
- if { [winfo class $w] == "Text" } {
- set window [jedit:text_to_top $w]
- set text $w
- } else {
- set window $w
- set text [jedit:top_to_text $w]
- }
- set mode [jedit:get_mode $window]
- set menubar [jedit:top_to_menubar $window]
- set buttonbar [jedit:top_to_buttonbar $window]
-
- if [winfo exists $buttonbar] {
- destroy $buttonbar
- }
-
- foreach key {0 1 2 3 4 5 6 7 8 9} {
- bind $text <Meta-Key-$key> { }
- }
-
- jedit:set_default_mode_prefs $mode
-
- if {"x[info procs mode:${mode}:init]" == "x"} {
- # we don't already have procs to enter the mode, so
- # look through a list of directories searching for the mode file:
- #
- set file ${mode}-mode.tcl
- foreach directory [list \
- $HOME/.tk/jeditmodes \
- $jstools_library/jeditmodes \
- $jstools_library/jedit/jeditmodes \
- ] {
- if [file isfile $directory/$file] {
- j:debug "Reading $file in $directory."
- j:source_config -directory $directory $file
- break
- }
- }
- }
- mode:${mode}:init $text
- jedit:mkmenus $menubar $text
- if $JEDIT_MODEPREFS($mode,buttonbar) {
- jedit:mkbuttonbar $buttonbar $text
- pack $buttonbar -after $menubar -fill x
- }
- if $JEDIT_MODEPREFS($mode,parenflash) {
- jedit:balance_bind $text
- }
- jedit:configure_text $text
- jedit:set_mode_label $window $mode
- }
-
- ######################################################################
- # set the mode a particular window is in
- # the window can be specified either as a text widget, or as that
- # text widget's corresponding toplevel window.
- ######################################################################
-
- proc jedit:set_mode { w newmode } {
- j:debug
- global MODES HOME
-
- if { [winfo class $w] == "Text" } {
- set window [jedit:text_to_top $w]
- set text $w
- } else {
- set window $w
- set text [jedit:top_to_text $w]
- }
-
- # do any cleanup necessary to cancel effect of current mode
- set oldmode plain
- catch {set oldmode $MODES($window)}
- if {[info procs mode:$oldmode:cleanup] != {}} {
- catch {mode:$oldmode:cleanup $text}
- }
-
- set MODES($window) $newmode
- }
-
- ######################################################################
- # return the mode a particular window is in
- # the window can be specified either as a text widget, or as that
- # text widget's corresponding toplevel window. if no mode has been
- # set for that window, returns "plain".
- ######################################################################
-
- proc jedit:get_mode { w } {
- # j:debug
- global MODES
-
- if { [winfo class $w] == "Text" } {
- set window [jedit:text_to_top $w]
- # set text $w
- } else {
- set window $w
- # set text [jedit:top_to_text $w]
- }
-
- if [info exists MODES($window)] {
- return $MODES($window)
- } else {
- return {plain}
- }
- }
-